package cn.px.service.request.bean.impl;

import cn.px.common.exception.BusinessException;
import cn.px.common.model.UserInfo;
import cn.px.common.util.IdGeneratorUtils;
import cn.px.common.util.JsonUtils;
import cn.px.common.util.SecurityUtils;
import cn.px.common.util.SpringContextHolder;
import cn.px.dao.entity.upms.SysRequestLog;
import cn.px.service.request.bean.BaseRequest;
import cn.px.service.request.dto.RequestDTO;
import cn.px.service.request.enums.SysRequestLogTypeEnum;
import cn.px.service.request.event.SysRequestLogEvent;
import cn.px.service.request.model.ResponseData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.function.Function;

/**
 * @Description
 * @author 品讯科技
 * @date 2024-08
 * @Version Copyright (c) 2019,安徽阡陌网络科技有限公司 All rights reserved.
 */
@Slf4j
@Service("baseRequest")
public class RequestImpl implements BaseRequest {

    @Override
    public <R> ResponseData request(SysRequestLogTypeEnum sysRequestLogTypeEnum, RequestDTO requestModel, Function<RequestDTO, ResponseData> consumer) {
        SysRequestLog requestLog = new SysRequestLog();
        if (requestModel.getIsUser() != null && requestModel.getIsUser()) {
            try {
                String clientId = SecurityUtils.getClientId();
                UserInfo userInfo = SecurityUtils.getUserInfo();
                requestLog.setCreatedUserId(userInfo.getUserId());
                requestLog.setCreatedUserName(userInfo.getRealName());
                requestLog.setUpdateUserId(userInfo.getUserId());
                requestLog.setUpdateUserName(userInfo.getRealName());
                requestLog.setClientId(clientId);
            } catch (Exception e) {
                requestLog.setRemark("获取用户失败信息");
            }
        }

        requestLog.setId(IdGeneratorUtils.getObjectId());
        requestLog.setType(sysRequestLogTypeEnum.getType());
        requestLog.setRequestType(sysRequestLogTypeEnum.getRequestType());
        requestLog.setUrl(requestModel.getUrl());
        requestLog.setMethod(requestModel.getMethod().getMethod());
        try {
            requestLog.setParams(JsonUtils.objectToJson(requestModel.getParams()));
        } catch (Exception e) {
            log.error("参数转json错误");
            requestLog.setRemark(requestLog.getRemark() + ",参数转json错误");
        }
        try {


            ResponseData apply = consumer.apply(requestModel);
            requestLog.setCode(apply.getCode());
            requestLog.setMessage(apply.getMessage());
            requestLog.setRequestId(apply.getRequestId());
            requestLog.setStatus(200);
            try {
                requestLog.setResult(JsonUtils.objectToJson(apply.getResult()));
            } catch (Exception e) {
                log.error("响应值转json错误");
                requestLog.setRemark(requestLog.getRemark() + ",响应值转json错误");
            }
            return apply;
        } catch (Exception e) {
            log.error("请求第三方发生异常", e);
            log.error("请求第三方发生异常");
            requestLog.setStatus(500);
            requestLog.setRemark(requestLog.getRemark() + ",请求第三方发生异常:" + e.getMessage());
            throw new BusinessException("执行请求异常");
        } finally {
            try {
                SpringContextHolder.publishEvent(new SysRequestLogEvent(requestLog));
            } catch (Exception e) {
                log.error("请求日志异步保存失败");
            }
        }

    }

}
